package lumis.service.association;

import java.util.Collection;
import java.util.List;

import lumis.content.ContentManagerFactory;
import lumis.content.core.ContentAssociation;
import lumis.content.core.ContentVersion;
import lumis.doui.source.IDataProvider;
import lumis.doui.source.ISourceData;
import lumis.doui.source.Source;
import lumis.doui.source.TabularData;
import lumis.doui.table.TableSource;
import lumis.portal.PortalException;
import lumis.portal.PortalObjectNotFoundException;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.serviceinstance.ServiceInstanceConfig;
import lumis.portal.serviceinstance.acl.ServiceInstancePermissions;
import lumis.util.ITransaction;

/**
 * Get the identifiers and primary names of the metadata contents associated 
 * to the provided content item id 
 *
 * @version $Revision: 9123 $ $Date: 2008-04-14 16:37:06 -0300 (Mon, 14 Apr 2008) $
 * @since 4.0.9
 */
public class AssociationDataProvider implements IDataProvider
{
	private boolean hasPermission(SessionConfig sessionConfig, String serviceInstanceId, ITransaction transaction) throws PortalException
	{
		ServiceInstanceConfig serviceInstanceConfig = ManagerFactory.getServiceInstanceManager().get(serviceInstanceId, transaction);
		ServiceInstancePermissions serviceInstancePermissions = ManagerFactory.getServiceInstanceAclManager().getPermissions(sessionConfig, serviceInstanceConfig.getServiceId(), transaction);
		return ManagerFactory.getServiceInstanceAclManager().checkPermission(sessionConfig, serviceInstanceId, serviceInstancePermissions.VIEW_SERVICE_INSTANCE, transaction);
	}
	
	@SuppressWarnings("unchecked")
	public void loadData(final SessionConfig sessionConfig, Source source, final ITransaction transaction) throws PortalException
	{
		TableSource tableSource = (TableSource)source;
	
		String contentId = (String)source.getParameterValue("contentId");
		if (contentId != null)
		{
			ContentVersion contentVersion;
			try
			{
				contentVersion = ContentManagerFactory.getContentManager().getPublishedContentVersion(contentId, null);
			}
			catch (PortalObjectNotFoundException e)
			{
				return; // won't load any data
			}
			
			// get user's principals list
			String userId = sessionConfig.getUserId();
			Collection<String> principalIds = ManagerFactory.getGroupManager().getMemberGroups(sessionConfig, userId, true, transaction);
			principalIds.add(userId);

			int startAt = tableSource.getStartAt();
			int maxRows = tableSource.getMaxRows();
			int rowCount = 0;
			TabularData tabularData = tableSource.getData();
			
			List<Object[]> results = ManagerFactory.getEntityManager().createQuery("select distinct " +
					"ac.id, acv.primaryName, ac.serviceInstanceId, acv.lastModifiedDateTime from " +
					"ContentVersion cv inner join cv.contentAssociations ca inner join ca.associatedContent ac inner join " +
					"ac.contentLocales acl inner join acl.publishedVersion acv inner join " +
					"acv.publications acp inner join acp.principalIds acpp where " +
					"cv = :contentVersion and ca.type = :associationType and " +
					"acpp in (:principalIds) and acp.published = true and " +
					"(acl.locale = :userLocale or (acl.locale = ac.defaultLocale and " +
					"not exists (select acl2 from ContentLocale acl2 where " +
					"acl2.content = ac and acl2.locale = :userLocale))) " +
					"order by acv.lastModifiedDateTime desc")
					.setParameter("contentVersion", contentVersion)
 					.setParameter("userLocale", sessionConfig.getLocale().toString())
 					.setParameter("principalIds", principalIds)
 					.setParameter("associationType", getAssociationType())
					.getResultList();
			for (Object[] resultRow: results)
			{
				String associatedContentId = (String)resultRow[0];
				String primaryName = (String)resultRow[1];
				String serviceInstanceId = (String)resultRow[2];
				if (hasPermission(sessionConfig, serviceInstanceId, transaction))
				{
					rowCount++;
					if (rowCount >= startAt && rowCount < maxRows + startAt)
					{
						ISourceData row = tabularData.addRow();
						row.put("associatedContentId", associatedContentId);
						row.put("associatedContent", primaryName);
					}
				}
			}
		}
	}
	
	protected String getAssociationType() throws PortalException
	{
		return ContentAssociation.TYPE_STANDARD;
	}
}
